#include<iostream>
#include<jsoncpp/json/json.h>
#include<string>
#include"httplib.h"
#include<mutex>
#include"table_dish.hpp"
#include"table_order.hpp"
using namespace std;

#define PORT 9090
#define WWWROOT "./wwwroot"
namespace ZhaoLiang{

  class Server{
    private:
      static void DishInsert(const httplib::Request& req, httplib::Response& rsp){
        //从请求中获取正文数据
        Json::Value dish;
        Json::Value err;
        Json::FastWriter writer;
        Json::Reader reader;
        bool ret = reader.parse(req.body, dish);
        if(ret == false){
          err["result"] = false;
          err["reason"] = "插入的菜单信息格式有误!";
          rsp.body = writer.write(err);
          rsp.status = 400;
          rsp.set_header("Content-Type", "application/json");
          cout << rsp.body << endl; 
          return;
        } 
        //调用数据库进行处理
        ret = _table_dish->DishInsert(dish);
        if(ret == false){
          err["result"] = false;
          err["reason"] = "数据库插入订单信息失败!";
          rsp.body = writer.write(err);
          rsp.status = 500;
          rsp.set_header("Content-Type", "application/json");
          cout << rsp.body << endl; 
          return;
        } 
        //填充响应信息
        rsp.status = 200;
      }

      static void DishDelete(const httplib::Request& req, httplib::Response& rsp){
        //从请求中获取要删除的id信息
        int dish_id = stoi(req.matches[1]);
        Json::FastWriter writer;
        Json::Value err;
        /*
           if(dish_id <= 0){
           err["result"] = false;
           err["reason"] = "dish_id error";
           rsp.body = writer.write(err);
           rsp.status = 400;
           rsp.set_header("Content-Type", "application/json");
           cout << rsp.body << endl; 
           return;
           }
           */
        //调用数据库进行删除
        bool ret = _table_dish->DishDelete(dish_id);
        if(ret == false){
          err["result"] = false;
          err["reason"] = "数据库删除菜单失败!";
          rsp.body = writer.write(err);
          rsp.status = 500;
          rsp.set_header("Content-Type", "application/json");
          cout << rsp.body << endl; 
          return;
        }
        //填充响应信息
        rsp.status = 200;
      }

      static void DishGetAll(const httplib::Request& req, httplib::Response& rsp){
        //调用数据库进行处理
        Json::Value dishes;
        Json::Value err;
        Json::FastWriter writer;
        bool ret = _table_dish->DishGetAll(&dishes);
        if(ret == false){
          err["result"] = false;
          err["reason"] = "数据库获取所有菜单失败!";
          rsp.body = writer.write(err);
          rsp.status = 500;
          rsp.set_header("Content-Type", "application/json");
          cout << rsp.body << endl; 
          return;
        }
        //填充响应信息
        rsp.status = 200;
        rsp.body = writer.write(dishes);
        rsp.set_header("Content-Type", "application/json");
      }

      static void DishGetOne(const httplib::Request& req, httplib::Response& rsp){
        //调用数据库获取要获取的菜单id
        int dish_id = stoi(req.matches[1]);
        Json::Value err;
        Json::FastWriter writer;
        Json::Value dish;
        /*
           if(dish_id <= 0){
           err["result"] = false;
           err["reason"] = "dish_id error";
           rsp.body = writer.write(err);
           rsp.status = 400;
           rsp.set_header("Content-Type", "application/json");
           cout << rsp.body << endl; 
           return;
           }
           */
        //调用数据库处理
        bool ret = _table_dish->DishGetOne(dish_id,&dish);
        if(ret == false){
          err["result"] = false;
          err["reason"] = "数据库获取指定菜单信息失败!";
          rsp.body = writer.write(err);
          rsp.status = 500;
          rsp.set_header("Content-Type", "application/json");
          cout << rsp.body << endl; 
          return;
        }
        //填充响应信息
        rsp.status = 200;
        rsp.body = writer.write(dish);
        rsp.set_header("Content-Type", "application/json");
      }

      static void DishUpdate(const httplib::Request& req, httplib::Response& rsp){
        //从请求中获取要修改的菜品id和修改信息
        int dish_id = stoi(req.matches[1]);
        Json::Value dish;
        Json::Value err;
        Json::FastWriter writer;
        Json::Reader reader;
        /*
           if(dish_id <= 0){
           err["result"] = false;
           err["reason"] = "dish_id error";
           rsp.body = writer.write(err);
           rsp.status = 400;
           rsp.set_header("Content-Type", "application/json");
           cout << rsp.body << endl; 
           return;
           }
           */
        bool ret = reader.parse(req.body, dish); 
        if(ret == false){
          err["result"] = false;
          err["reason"] = "数据库要修改的菜单格式有误!";
          rsp.body = writer.write(err);
          rsp.status = 500;
          rsp.set_header("Content-Type", "application/json");
          cout << rsp.body << endl; 
          return;

        }
        //调用数据库进行处理
        ret = _table_dish->DishUpdate(dish_id, dish);
        if(ret == false){
          err["result"] = false;
          err["reason"] = "数据库修改指定菜单信息失败!";
          rsp.body = writer.write(err);
          rsp.status = 500;
          rsp.set_header("Content-Type", "application/json");
          cout << rsp.body << endl; 
          return;
        }
        //填充响应信息
        rsp.status = 200;
      }

      static void OrderInsert(const httplib::Request& req, httplib::Response& rsp){
        //从请求中获取正文数据
        Json::Value order;
        Json::Value err;
        Json::FastWriter writer;
        Json::Reader reader;
        bool ret = reader.parse(req.body, order);
        if(ret == false){
          err["result"] = false;
          err["reason"] = "插入的订单信息格式有误!";
          rsp.body = writer.write(err);
          rsp.status = 400;
          rsp.set_header("Content-Type", "application/json");
          cout << rsp.body << endl; 
          return;
        } 
        //调用数据库进行处理
        ret = _table_order->OrderInsert(order);
        if(ret == false){
          err["result"] = false;
          err["reason"] = "数据库插入订单信息失败!";
          rsp.body = writer.write(err);
          rsp.status = 500;
          rsp.set_header("Content-Type", "application/json");
          cout << rsp.body << endl; 
          return;
        } 
        //填充响应信息
        rsp.status = 200;
      }

      static void OrderDelete(const httplib::Request& req, httplib::Response& rsp){
        //从请求中获取要删除的id信息
        int order_id = stoi(req.matches[1]);
        Json::FastWriter writer;
        Json::Value err;
        /*
           if(order_id <= 0){
           err["result"] = false;
           err["reason"] = "order_id error";
           rsp.body = writer.write(err);
           rsp.status = 400;
           rsp.set_header("Content-Type", "application/json");
           cout << rsp.body << endl; 
           return;
           }
           */
        //调用数据库进行删除
        bool ret = _table_order->OrderDelete(order_id);
        if(ret == false){
          err["result"] = false;
          err["reason"] = "数据库删除订单失败!";
          rsp.body = writer.write(err);
          rsp.status = 500;
          rsp.set_header("Content-Type", "application/json");
          cout << rsp.body << endl; 
          return;
        }
        //填充响应信息
        rsp.status = 200;
      }

      static void OrderGetAll(const httplib::Request& req, httplib::Response& rsp){
        //调用数据库进行处理
        Json::Value orderes;
        Json::Value err;
        Json::FastWriter writer;
        bool ret = _table_order->OrderGetAll(&orderes);
        if(ret == false){
          err["result"] = false;
          err["reason"] = "数据库获取所有订单失败!";
          rsp.body = writer.write(err);
          rsp.status = 500;
          rsp.set_header("Content-Type", "application/json");
          cout << rsp.body << endl; 
          return;
        }
        //填充响应信息
        rsp.status = 200;
        rsp.body = writer.write(orderes);
        rsp.set_header("Content-Type", "application/json");
      }

      static void OrderGetOne(const httplib::Request& req, httplib::Response& rsp){
        //调用数据库获取要获取的订单id
        int order_id = stoi(req.matches[1]);
        Json::Value err;
        Json::FastWriter writer;
        Json::Value order;
        /*
           if(order_id <= 0){
           err["result"] = false;
           err["reason"] = "order_id error";
           rsp.body = writer.write(err);
           rsp.status = 400;
           rsp.set_header("Content-Type", "application/json");
           cout << rsp.body << endl; 
           return;
           }
           */
        //调用数据库处理
        bool ret = _table_order->OrderGetOne(order_id,&order);
        if(ret == false){
          err["result"] = false;
          err["reason"] = "数据库获取指定订单信息失败!";
          rsp.body = writer.write(err);
          rsp.status = 500;
          rsp.set_header("Content-Type", "application/json");
          cout << rsp.body << endl; 
          return;
        }
        //填充响应信息
        rsp.status = 200;
        rsp.body = writer.write(order);
        rsp.set_header("Content-Type", "application/json");
      }

      static void OrderUpdate(const httplib::Request& req, httplib::Response& rsp){
        //从请求中获取要修改的菜品id和修改信息
        int order_id = stoi(req.matches[1]);
        Json::Value order;
        Json::Value err;
        Json::FastWriter writer;
        Json::Reader reader;
        /*
           if(order_id <= 0){
           err["result"] = false;
           err["reason"] = "order_id error";
           rsp.body = writer.write(err);
           rsp.status = 400;
           rsp.set_header("Content-Type", "application/json");
           cout << rsp.body << endl; 
           return;
           }
           */
        bool ret = reader.parse(req.body, order); 
        if(ret == false){
          err["result"] = false;
          err["reason"] = "数据库要修改的订单格式有误!";
          rsp.body = writer.write(err);
          rsp.status = 500;
          rsp.set_header("Content-Type", "application/json");
          cout << rsp.body << endl; 
          return;

        }
        //调用数据库进行处理
        ret = _table_order->OrderUpdate(order_id, order);
        if(ret == false){
          err["result"] = false;
          err["reason"] = "数据库修改指定订单信息失败!";
          rsp.body = writer.write(err);
          rsp.status = 500;
          rsp.set_header("Content-Type", "application/json");
          cout << rsp.body << endl; 
          return;
        }
        //填充响应信息
        rsp.status = 200;
      }
    public: 
      /*
         static httplib::Server* GetServer(){
         if(_server == NULL){
         _mutex.lock();
         if(_server == NULL)
         _server = new httplib::Server();
         _mutex.unlock();
         }
         return _server;
         }
         static TableDish* GetDish(){
         if(_table_dish == NULL){
         _mutex.lock();
         if(_table_dish == NULL)
         _table_dish = new TableDish();
         _mutex.unlock();
         }
         return _table_dish;
         }
         static TableOrder* GetOrder(){
         if(_table_order == NULL){
         _mutex.lock();
         if(_table_order == NULL)
         _table_order = new TableOrder();
         _mutex.unlock();
         }
         return _table_order;
         }
         */
      Server(uint16_t port = PORT):_port(port){}
      void RunServer(){
        /*
           _server = GetServer();
           _table_dish = GetDish();
           _table_order = GetOrder();
           */
        _server = new httplib::Server();
        _server->set_mount_point("/", WWWROOT);

        _server->Post(R"(/dish)",DishInsert);
        _server->Get(R"(/dish/(\d+))", DishGetOne);
        _server->Get(R"(/dish)",DishGetAll);
        _server->Delete(R"(/dish/(\d+))", DishDelete);
        _server->Put(R"(/dish/(\d+))", DishUpdate);

        _server->Post(R"(/order)",OrderInsert);
        _server->Get(R"(/order/(\d+))", OrderGetOne);
        _server->Get(R"(/order)",OrderGetAll);
        _server->Delete(R"(/order/(\d+))", OrderDelete);
        _server->Put(R"(/order/(\d+))", OrderUpdate);

        _server->listen("0.0.0.0", _port);
      }
      /*
         private:
      //定义在私有函数里，Destory会自动析构吗?---会，对于Destory来说
      class Destory{
      public:
      Destory(){cout << "Destory" << endl;}
      ~Destory(){
      if(_server != NULL){
      delete _server;
      _server = NULL;
      }
      if(_table_dish != NULL){
      delete _table_dish;
      _table_dish = NULL;
      }
      if(_table_order != NULL){
      delete _table_order;
      _table_order = NULL;
      }
      }
      };
      ~Server(){}
      Server(const Server& S) = delete;
      Server& operator=(const Server& S) = delete;
      */
    private:
      /*
         static httplib::Server* _server;
         static mutex _mutex;
         static TableDish* _table_dish; 
         static TableOrder* _table_order;
         static uint16_t _port;
         Destory _Del;//单例模式的析构--嵌套类自行析构(如果使用原类析构，就会导致delete的无线递归)
         */
      httplib::Server* _server;
      static TableDish* _table_dish; 
      static TableOrder* _table_order;
      uint16_t _port;
  };
  /*
     httplib::Server* Server::_server = NULL;
     mutex Server::_mutex;
     TableDish* Server::_table_dish = NULL;
     TableOrder* Server::_table_order = NULL;
     uint16_t Server::_port = PORT;
  //Server::Destory Server::_Del;
  */

  TableDish* Server::_table_dish = new TableDish();
  TableOrder* Server::_table_order = new TableOrder();
}
